package com.george.minio.controller;


import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.george.minio.config.MinioConfig;
import com.george.minio.dto.MinioFileDTO;
import com.george.minio.dto.Result;
import com.george.minio.entity.MinioFileDAO;
import com.george.minio.service.MinioFileService;
import com.george.minio.utils.MinioClientUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * (MinioFile)表控制层
 *
 * @author makejava
 * @since 2023-05-16 17:39:13
 */
@Slf4j
@RestController
@RequestMapping("minioFile")
public class MinioFileController {
    /**
     * 服务对象
     */
    @Resource
    private MinioFileService minioFileService;

    /**
     * 分页查询所有数据
     *
     * @param pageSize 页容量
     * @param pageNum 页码
     * @param minioFileDao 查询实体
     * @return Result 所有数据
     */
    @PostMapping("/selectAll/{pageSize}/{pageNum}")
    public Result selectAll(@PathVariable int pageSize, @PathVariable int pageNum,@RequestBody MinioFileDAO minioFileDao) {
        Page<MinioFileDAO> page = new Page<>();
        page.setSize(pageSize);
        page.setCurrent(pageNum);
        return Result.successResult(this.minioFileService.page(page, new QueryWrapper<>(minioFileDao)));
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public Result selectOne(@PathVariable Serializable id) {
        return Result.successResult(this.minioFileService.getById(id));
    }

    /**
     * 新增数据
     *
     * @param minioFileDao 实体对象
     * @return 新增结果
     */
    @PostMapping
    public Result insert(@RequestBody MinioFileDAO minioFileDao) {
        return Result.successResult(this.minioFileService.save(minioFileDao));
    }

    /**
     * @description: 修改数据
     * @author: George
     * @date: 2023/5/17 14:23
     * @param minioFileDao 实体对象
     * @return Result 修改结果
     */
    @PutMapping
    public Result update(@RequestBody MinioFileDAO minioFileDao) {
        return Result.successResult(this.minioFileService.updateById(minioFileDao));
    }

    /**
     * @description: 删除数据
     * @author: George
     * @date: 2023/5/17 14:21
     * @param: idList 主键集合
     * @return: Result 删除结果
     */
    @DeleteMapping
    public Result delete(@RequestParam("idList") List<Long> idList) {
        return Result.successResult(this.minioFileService.removeByIds(idList));
    }

    private MinioClientUtils minioClientUtils;

    private MinioConfig minioConfig;

    /**
     * 上传文件到Minio
     * @author George
     * @date 2023/5/17 14:16
     * @param files
     * @return Result
     */
    @PostMapping(value = {"/web/uploadFile"})
    @ResponseBody
    public Result uploadFile(@RequestParam("files") List<MultipartFile> files) {
        log.info(files.toString());
        if (CollectionUtils.isEmpty(files)) {
            return Result.failResult("未选择文件！");
        }

        List<MinioFileDTO> minioFileDTOList = new ArrayList<>();
        for (MultipartFile file : files) {
            String originalFilename = file.getOriginalFilename();
            //获取文件拓展名
            String extName = FileUtil.extName(originalFilename);
            log.info("文件拓展名:" + extName);
            //生成新的文件名，存入到minio
            long millSeconds = Instant.now().toEpochMilli();
            String minioFileName = millSeconds + RandomStringUtils.randomNumeric(12) + "." + extName;
            String contentType = file.getContentType();
            log.info("文件mime:{}", contentType);
            //返回文件大小,单位字节
            long size = file.getSize();
            log.info("文件大小：" + size);
            try {
                String bucketName = minioConfig.getBucketName();
                minioClientUtils.putObject(bucketName, file, minioFileName);
                String fileUrl = minioClientUtils.getObjectUrl(bucketName, minioFileName);
                MinioFileDAO minioFile = new MinioFileDAO();
                minioFile.setOriginalFileName(originalFilename);
                minioFile.setFileExtName(extName);
                minioFile.setFileName(minioFileName);
                minioFile.setFileSize(size);
                minioFile.setMime(contentType);
                minioFile.setIsDelete(NumberUtils.INTEGER_ZERO);
                minioFile.setFileUrl(fileUrl);
                minioFile.setCreateTime(new Date());
                boolean insert = minioFile.insert();
                if (insert) {
                    MinioFileDTO minioResponseDTO = new MinioFileDTO();
                    minioResponseDTO.setFileId(minioFile.getId());
                    minioResponseDTO.setOriginalFileName(originalFilename);
                    minioResponseDTO.setFileUrl(fileUrl);
                    minioFileDTOList.add(minioResponseDTO);
                }


            } catch (Exception e) {
                log.error("上传文件出错:{}", e);
                return Result.failResult("上传文件出错");

            }
        }

        return Result.successResult(minioFileDTOList);
    }


    /**
     * 仅仅用于测试，是否可以正常上传文件到Minio
     * @author George
     * @date 2023/5/17 14:18
     * @return Result
     */
    @GetMapping("/test")
    @ApiOperation(value = "测试minio文件上传")
    public Result testPutObject() throws Exception {
        FileInputStream fileInputStream = new FileInputStream("C:\\新建文本文档.txt");
        boolean bs = minioClientUtils.putObject(minioConfig.getBucketName(), "新建文本文档.txt", fileInputStream, "txt/plain");
        log.info("上传成功?" + bs);
        return Result.successResult("上传成功");
    }
}

